#region Header
//=============================================================================
//                          GShield (Game Shield)
//=============================================================================
//
// Original Programmer: Shawn Jackson
// Company: WaveTech Digital Technologies (www.wtdt.com)
// Copyright: (c) 2006 WaveTech Digital Technologies, All Rights Reserved.
// Assembly: Engine
// Code File Name: WindowManager.cs
// Code File Date: 5/23/2007
//
// Code File Info: Uniform Window (Form and Dialog) access manager
//=============================================================================
/*
 * UPDATES
 * -------
 */
#endregion Header

#region License
/*
  GShield - Game Shield
  Copyright (C) 2006-2007 WaveTech Digital Technologies, Inc.
                                http://www.wtdt.com

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
#endregion License

#region Includes
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
#endregion Includes

namespace WaveTech.GShield.Engine.Managers
{
	/// <summary>
	/// Used to manage window (Form) instances inside the GShield Manager Application.
	/// </summary>
	/// <remarks>
	/// Originally derived from Dominik Reichl's KeePass GlobalWindowManager class. Need
	/// a central location to house the windows beacuse forms were being opened up from
	/// multiple locations.
	/// </remarks>
	public static class WindowManager
	{
		#region Private Members
		private static List<KeyValuePair<String, Form>> m_Windows = new List<KeyValuePair<String, Form>>();
		private static List<CommonDialog> m_Dialogs = new List<CommonDialog>();
		private static Form m_MdiParent;
		#endregion Private Members

		#region Public Properties
		public static int WindowCount
		{
			get
			{
				return (m_Windows.Count + m_Dialogs.Count);
			}
		}

		public static Form MdiParent
		{
			get { return m_MdiParent; }
			set { m_MdiParent = value; }
		}
		#endregion Public Properties

		#region Add Window
		/// <summary>
		/// Adds a Window into the WindowManager system using it's Text as it;s name.
		/// </summary>
		/// <param name="form">Form to add into the WindowManager system</param>
		public static void AddWindow(Form form)
		{
			AddWindow(form.Text, form, true);
		}

		/// <summary>
		/// Adds a Window into the WindowManager system using it's Text as it;s name.
		/// </summary>
		/// <param name="form">Form to add into the WindowManager system</param>
		/// <param name="hookToParent"></param>
		public static void AddWindow(Form form, bool hookToParent)
		{
			AddWindow(form.Text, form, hookToParent);
		}

		/// <summary>
		/// Adds a Windows into the WindowManager system without a custom name.
		/// </summary>
		/// <param name="name">Name to give this Form</param>
		/// <param name="form">Form to add into the WindowManger system</param>
		/// <param name="hookToParent">Determines if the window should be an Mdi Child of MdiParent</param>
		public static void AddWindow(String name, Form form, bool hookToParent)
		{
			if (name == null) throw new ArgumentNullException("name");
			if (form == null) throw new ArgumentNullException("form");

			KeyValuePair<String, Form> kvp = new KeyValuePair<String, Form>(name, form);

			if (DoesFormExist(name))
				BringToFront(form, hookToParent);
			else
			{
				if (hookToParent)
					if (m_MdiParent != null)
						form.MdiParent = m_MdiParent;

				m_Windows.Add(kvp);
				form.Show();
			}
		}
		#endregion Add Window

		#region Add Dialog
		public static void AddDialog(CommonDialog dlg)
		{
			Debug.Assert(dlg != null);
			if (dlg == null) throw new ArgumentNullException("dlg");

			m_Dialogs.Add(dlg);
		}
		#endregion Add Dialog

		#region Remove Window
		/// <summary>
		/// Removes a Form from the WindowManager by Form
		/// </summary>
		/// <param name="form">Form to remove</param>
		public static void RemoveWindow(Form form)
		{
			if (form == null) throw new ArgumentNullException("form");

			for (int i = 0; i < m_Windows.Count; ++i)
			{
				if (m_Windows[i].Value == form)
				{
					m_Windows.RemoveAt(i);
					return;
				}
			}
		}

		/// <summary>
		/// Removes a Form from the WindowsManager by Name
		/// </summary>
		/// <param name="name">Name of the form to remove</param>
		public static void RemoveWindow(String name)
		{
			if (name == null) throw new ArgumentNullException("name");

			for (int i = 0; i < m_Windows.Count; ++i)
			{
				if (m_Windows[i].Key == name)
				{
					m_Windows.RemoveAt(i);
					return;
				}
			}
		}
		#endregion Remove Window

		#region Remove Dialog
		/// <summary>
		/// Removes a Dialog from the WindowManager
		/// </summary>
		/// <param name="dlg">Dialog to remove</param>
		public static void RemoveDialog(CommonDialog dlg)
		{
			Debug.Assert(dlg != null);
			if (dlg == null) throw new ArgumentNullException("dlg");

			Debug.Assert(m_Dialogs.IndexOf(dlg) >= 0);
			m_Dialogs.Remove(dlg);
		}
		#endregion Remove Dialog

		#region Close All Windows
		/// <summary>
		/// Closes all windows in the WindowManager
		/// </summary>
		public static void CloseAllWindows()
		{

			KeyValuePair<String, Form>[] vWindows = m_Windows.ToArray();
			Array.Reverse(vWindows); // Close windows in reverse order

			foreach (KeyValuePair<String, Form> kvp in vWindows)
			{
				kvp.Value.DialogResult = DialogResult.Cancel;
				kvp.Value.Close();

				Application.DoEvents();
			}
		}
		#endregion Close All Windows

		#region Bring To Front
		/// <summary>
		/// Brings an existing Window to the Front by Form
		/// </summary>
		/// <param name="form">Form to bring to the front</param>
		/// <param name="hookToParent">Determines if the window should be an Mdi Child of MdiParent</param>
		public static void BringToFront(Form form, bool hookToParent)
		{
			BringToFront(form.Text, form, hookToParent);
		}

		/// <summary>
		/// Brings an existing Window to the Front by Name
		/// </summary>
		/// <param name="name">Name of the form to bring to the front</param>
		/// <param name="form">Form to bring to the front</param>
		/// <param name="hookToParent">Determines if the window should be an Mdi Child of MdiParent</param>
		public static void BringToFront(String name, Form form, bool hookToParent)
		{
			if (name == null) throw new ArgumentNullException("name");
			if (form == null) throw new ArgumentNullException("form");

			int index = 0;

			for (int i = 0; i < m_Windows.Count; ++i)
			{
				if (m_Windows[i].Key == name)
				{
					index = i;
					break;
				}
			}

			if (m_Windows[index].Value.IsDisposed)
			{
				RemoveWindow(name);
				AddWindow(name, form, hookToParent);
			}
			else
			{
				m_Windows[index].Value.BringToFront();
			}
		}
		#endregion Bring To Front

		#region Does Form Exist
		/// <summary>
		/// Checks to see if a form exists in the WindowManager
		/// </summary>
		/// <param name="name">Name of the form to check</param>
		public static bool DoesFormExist(String name)
		{
			if (name == null) throw new ArgumentNullException("name");

			for (int i = 0; i < m_Windows.Count; ++i)
			{
				if (m_Windows[i].Key == name)
				{
					return true;
				}
			}

			return false;
		}
		#endregion Does Form Exist
	}
}